package com.me.collector;

import java.util.ArrayList;
import java.util.Random;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.ParticleEffectPool.PooledEffect;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.Array;
import com.me.collector.Definitions.ItemType;
import com.me.collector.items.Apple;
import com.me.collector.items.Bomb;
import com.me.collector.items.Cherry;

// Manages all FallingObjectLists
public class FallingItems {
	private World world;
	private Physics physics;
	private Boolean endlessSpawn = false;
	private float time = 0f;
	
	
	// Falling Object Lists
	// These two lists shall work parallel. For each Item a FallingObjectList will be created.
	private ArrayList<Item> items = new ArrayList<Item>();
	private ArrayList<FallingObjectList> fObjectLists = new ArrayList<FallingObjectList>();
	private Array<PooledEffect> effects; // Particle effects
	
	public FallingItems(World world)
	{
		// Default Physics (use setPhysics to set Physics)
		this.physics = new Physics(1f, 0.5f, 0.5f, 0f);
		this.world = world;
		
		// Load Items
		items.add(new Apple());
		items.add(new Cherry());
		items.add(new Bomb());
		
		// Init Lists
		for(Item i:items)
			fObjectLists.add(new FallingObjectList(world, physics, i));
		effects = new Array();
	}
	
	public void update()
	{
		if(endlessSpawn)
		{
			time -= Gdx.graphics.getDeltaTime();
			if(time < 0)
			{
				time = (float)Math.random() * 3f;
				int rnd = new Random().nextInt(items.size());
				addItem(items.get(rnd).getType(), (float)Math.random() * Definitions.SCREEN_WIDTH - items.get(rnd).getWidth());
			}
		}
		for(FallingObjectList l:fObjectLists)
			l.update();
	}
	
	// Creates Particle effect
	public void addEffect(PooledEffect effect, float x, float y) {
		effect.setPosition(x, y);
		effects.add(effect);
	}
	
	public void draw(SpriteBatch batch)
	{
		for(FallingObjectList l:fObjectLists)
			l.draw(batch);
		drawParticles(batch, Gdx.graphics.getDeltaTime());
	}
	
	// draws collect particle effect
	private void drawParticles(SpriteBatch batch, float delta) {
		for (int i = effects.size - 1; i >= 0; i--) {
			PooledEffect effect = effects.get(i);
			effect.draw(batch, delta);
			if (effect.isComplete()) {
				effect.free();
				effects.removeIndex(i);
			}
		}
	}
	
	public void clear()
	{
		for(FallingObjectList l:fObjectLists)
			l.clear();
	}
	
	public void dispose()
	{
		for(FallingObjectList l:fObjectLists)
			l.dispose();
	}
		
	public FallingObjectList getListByItem(Item i)
	{
		return fObjectLists.get(items.indexOf(i));
	}
	
	public void addItem(ItemType type)
	{
		for(Item i:items)
			if(i.getType() == type)
			{
				getListByItem(i).add(1);
				break;
			}
	}
	
	public void addItem(ItemType type, float x)
	{
		for(Item i:items)
			if(i.getType() == type)
			{
				getListByItem(i).add(x);
				break;
			}
	}
	
	// Debug
	public void setEndlessSpawn()
	{
		endlessSpawn = true;
	}
	
	// properties	
	
	public void setPhysics(Physics physics)
	{
		this.physics = physics;
	}
	
	// Don't use this method anymore. better cast the body's userData to Item.
	/*
	public Item getItemByBody(Body body)
	{
		for(int i = 0; i < fObjectLists.size(); i++)
			if(fObjectLists.get(i).Contains(body))
				return items.get(i);
		return null;
	}
	*/
	
	public FallingObject getFallingObjectByBody(Body body)
	{
		FallingObject o;
		for(FallingObjectList l:fObjectLists)
		{
			if(l.getItem() == (Item)body.getUserData())
			{
				o = l.getByBody(body);
				if( o != null)
					return o;
			}
		}
		return null;
	}
}
